package cn.minsh.lims.eoms.modules.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.minsh.lims.eoms.common.exception.RRException;
import cn.minsh.lims.eoms.common.utils.DateUtils;
import cn.minsh.lims.eoms.common.utils.ObjectToMapUtils;
import cn.minsh.lims.eoms.common.utils.PageUtils;
import cn.minsh.lims.eoms.common.utils.Query;
import cn.minsh.lims.eoms.modules.app.controller.req.UserInspectionPlanReq;
import cn.minsh.lims.eoms.modules.app.controller.req.app.AppUserInspectionListReq;
import cn.minsh.lims.eoms.modules.app.controller.req.app.AppUserInspectionSubmitAndCloseReq;
import cn.minsh.lims.eoms.modules.app.controller.req.app.AppUserInspectionSubmitResultReq;
import cn.minsh.lims.eoms.modules.app.controller.res.*;
import cn.minsh.lims.eoms.modules.app.dao.UserInspectionPlanDao;
import cn.minsh.lims.eoms.modules.app.entity.*;
import cn.minsh.lims.eoms.modules.app.enums.BusiTypeEnum;
import cn.minsh.lims.eoms.modules.app.enums.FrequencyEnum;
import cn.minsh.lims.eoms.modules.app.enums.PlanResultEnum;
import cn.minsh.lims.eoms.modules.app.enums.PlanStatusEnum;
import cn.minsh.lims.eoms.modules.app.service.*;
import cn.minsh.lims.eoms.modules.app.utils.CodeUtils;
import cn.minsh.lims.eoms.modules.app.utils.Constants;
import cn.minsh.lims.eoms.modules.app.utils.LocalDateUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import javafx.scene.effect.SepiaTone;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.policy.ExceptionClassifierRetryPolicy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collector;
import java.util.stream.Collectors;


/**
 * @author Administrator
 */
@Service("userInspectionPlanService")
public class UserInspectionPlanServiceImpl extends ServiceImpl<UserInspectionPlanDao, UserInspectionPlanEntity> implements UserInspectionPlanService {


    @Autowired
    private InspectionPlanService inspectionPlanService ;
    @Autowired
    private UserInspectionPlanScopeService userInspectionPlanScopeService ;
    @Autowired
    private UserInspectionPlanContentService userInspectionPlanContentService ;
    @Autowired
    private PicService picService ;
    @Autowired
    private PlanRemindService remindService ;
    @Autowired
    private PlanAgentService planAgentService ;

    @Override
    public PageUtils queryPage(UserInspectionPlanReq req) {
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByType(BusiTypeEnum.INSPECTIONPLAN.getCode()) ;

        QueryWrapper<UserInspectionPlanEntity> queryWrapper = new QueryWrapper<>() ;
        queryWrapper.eq("is_del",0) ;
        if(req.getStatus()!=null) {
            queryWrapper.eq("status",req.getStatus()) ;
        }
        if (StringUtils.isNotBlank(req.getName())){
            queryWrapper.like("name","%"+req.getName()+"%") ;
        }
        if (!CollectionUtils.isEmpty(req.getCreateByList())){
            queryWrapper.in("create_by",req.getCreateByList()) ;
        }
        if (!CollectionUtils.isEmpty(req.getAgentIdList())){
            //查询工单id列表
            
            if (!CollectionUtils.isEmpty(planAgentEntityList)){
                List<Long> orderIdList = planAgentEntityList.stream().filter(pa->req.getAgentIdList().indexOf(pa.getAgentId())>-1).map(PlanAgentEntity::getPlanId).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(orderIdList)){
                    queryWrapper.in("id",orderIdList) ;
                }
            }
        }
        if (req.getResult()!= null){
            queryWrapper.eq("result",req.getResult()) ;
        }
        if (StringUtils.isNotBlank(req.getOrder()) && StringUtils.isNotBlank(req.getSort())){
            queryWrapper.orderBy(true,"asc".equals(req.getSort().toLowerCase()),req.getOrder()) ;
        }else{
            queryWrapper.orderByDesc("id") ;
        }

        IPage<UserInspectionPlanEntity> page = this.page(
                new Query<UserInspectionPlanEntity>().getPage(ObjectToMapUtils.setConditionMap(req)),
                queryWrapper
        );

        List<UserInspectionPlanRes> retList = new ArrayList<>() ;

        IPage<UserInspectionPlanRes> retPage = new Page<>(page.getCurrent(),page.getSize()) ;
        retPage.setPages(page.getPages()) ;
        retPage.setTotal(page.getTotal()) ;

        if (!CollectionUtils.isEmpty(page.getRecords())){
            //查询所有范围
            List<UserInspectionPlanScopeEntity> planScopeEntityList= userInspectionPlanScopeService.list() ;

            page.getRecords().forEach(e->{
                UserInspectionPlanRes res = new UserInspectionPlanRes() ;
                BeanUtils.copyProperties(e,res);
                //添加首次巡检时间
                res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
                //时间
                if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())){
                    res.setPlanTimeScope(LocalDateUtils.getWeekTimeStr(e.getPlanStartTime(),e.getPlanEndTime()));
                }else{
                    res.setPlanTimeScope(LocalDateUtils.getTimeStr(e.getPlanStartTime(),e.getPlanEndTime()));
                }
                res.setStatusDesc(PlanStatusEnum.getDesc(e.getStatus()));
                res.setResultDesc(PlanResultEnum.getDesc(e.getResult()));
                if (!CollectionUtils.isEmpty(planScopeEntityList)){
                    List<Long> scopeIdList = planScopeEntityList.stream().filter(c->c.getUserInspectionPlanId().equals(e.getId())).map(UserInspectionPlanScopeEntity::getScopeId).collect(Collectors.toList()) ;
                    res.setScopeList(scopeIdList);
                }
                if (!CollectionUtils.isEmpty(planAgentEntityList)){
                    res.setAgentIdList(planAgentEntityList.stream().filter(pa->pa.getPlanId().equals(e.getId())).map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
                }
                
                retList.add(res) ;
            });
        }

        retPage.setRecords(retList) ;

        return new PageUtils(retPage);
    }

    @Override
    public void saveBatchUserPlan(List<InspectionPlanRes> list) {

        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(e->createUserPlan(e));
        }
    }

    @Override
    public UserInspectionPlanInfoRes queryById(Long id) {
        UserInspectionPlanInfoRes res = new UserInspectionPlanInfoRes() ;
        UserInspectionPlanEntity planEntity= getById(id) ;
        if(planEntity==null||planEntity.getId()==null){
            throw new RRException("记录不存在") ;
        }
        BeanUtil.copyProperties(planEntity,res,true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        //查询经办人列表
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONORDER.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planAgentEntityList)){
            res.setAgentIdList(planAgentEntityList.stream().map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
        }
        //查询巡检范围
        QueryWrapper<UserInspectionPlanScopeEntity> scopeEntityQueryWrapper = new QueryWrapper<>() ;
        scopeEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanScopeEntity> scopeList = userInspectionPlanScopeService.list(scopeEntityQueryWrapper) ;
        if (!CollectionUtils.isEmpty(scopeList)){
            List<Long> scopeIdList = scopeList.stream().map(UserInspectionPlanScopeEntity::getScopeId).collect(Collectors.toList()) ;
            res.setScopeList(scopeIdList);
        }
        //提醒时间
        QueryWrapper<PlanRemindEntity> remindEntityQueryWrapper = new QueryWrapper<>() ;
        remindEntityQueryWrapper.eq("plan_id",planEntity.getPlanId()) ;
        List<PlanRemindEntity> remindList = remindService.list(remindEntityQueryWrapper) ;
        res.setRemindList(remindList.stream().map(PlanRemindEntity::getLeadTime).collect(Collectors.toList()));
        //巡检内容
        QueryWrapper<UserInspectionPlanContentEntity> contentEntityQueryWrapper = new QueryWrapper<>() ;
        contentEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanContentEntity> contentPlanList = userInspectionPlanContentService.list(contentEntityQueryWrapper) ;
        List<String> contentList = new ArrayList<>() ;
        contentPlanList.forEach(e->{
            if (!contentList.contains(e.getContent())){
                contentList.add(e.getContent()) ;
            }
        });
        res.setContentList(contentList);
        //巡检内容,选件图片是巡检范围的图片
        List<PicEntity> picEntityList = picService.listByType(BusiTypeEnum.INSPECTIONORDER.getCode()) ;
        List<UserInspectionPlanInfoRes.PlanResult> planResultList = new ArrayList<>() ;
        //待巡检
        AtomicInteger beInspectedCount = new AtomicInteger() ;
        //已巡检
        AtomicInteger inspectedCount = new AtomicInteger() ;
        //逾期未巡检
        AtomicInteger overdueCount = new AtomicInteger() ;
        Set<Long> executorIdSet = new HashSet<>() ;
        scopeList.forEach(e->{
            if (e.getExecutorId()!=null) {
                executorIdSet.add(e.getExecutorId());
            }
            UserInspectionPlanInfoRes.PlanResult result = new UserInspectionPlanInfoRes.PlanResult() ;
            BeanUtil.copyProperties(e,result,true,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            result.setPicList(picEntityList.stream().filter(p->p.getBusiId().equals(e.getId())).map(PicEntity::getPic).collect(Collectors.toList()));

            List<UserInspectionPlanInfoRes.PlanResult.Content> resultContent = new ArrayList<>() ;
            contentPlanList.stream().filter(p->p.getUserInspectionPlanScopeId().equals(e.getId())).forEach(pp->{
                UserInspectionPlanInfoRes.PlanResult.Content content = new UserInspectionPlanInfoRes.PlanResult.Content() ;
                BeanUtil.copyProperties(pp,content,true,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                resultContent.add(content) ;
            });
            if (result.getResult() == -1){
                beInspectedCount.set(beInspectedCount.addAndGet(1) );
            }else if (result.getResult() == 2){
                overdueCount.set(overdueCount.addAndGet(1));
            }else{
                inspectedCount.set(inspectedCount.addAndGet(1));
            }
            result.setContentList(resultContent);
            planResultList.add(result) ;
        });

        if (executorIdSet.size()>0) {
            res.setExecutorIdList(executorIdSet.stream().distinct().collect(Collectors.toList()));
        }
        res.setBeInspectedCount(beInspectedCount.get());
        res.setInspectedCount(inspectedCount.get());
        res.setOverdueCount(overdueCount.get());

        res.setPlanResultList(planResultList);
        res.setStatusDesc(PlanStatusEnum.getDesc(res.getStatus()));
        res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
        //时间
        if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())||FrequencyEnum.WORKING.getCode().equals(res.getFrequency())) {
            res.setPlanTimeScope(LocalDateUtils.getWeekTimeStr(res.getPlanStartTime(), res.getPlanEndTime()));
        }else{
            res.setPlanTimeScope(LocalDateUtils.getTimeStr(res.getPlanStartTime(),res.getPlanEndTime()));
        }
        return res ;
    }

    @Override
    public PageUtils queryAppPage(AppUserInspectionListReq req,Long userId) {
        //根据经办人查询工单id列表
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndAgentId(BusiTypeEnum.INSPECTIONPLAN.getCode(),userId) ;
        if (CollectionUtils.isEmpty(planAgentEntityList)){
            throw new RRException("无记录") ;
        }
        QueryWrapper<UserInspectionPlanEntity> queryWrapper = new QueryWrapper<>() ;
        queryWrapper.in("id",planAgentEntityList.stream().map(PlanAgentEntity::getPlanId).collect(Collectors.toList())) ;
        queryWrapper.eq("is_del",0) ;
        if (req.getOrderType()==1){
            //待办列表，经办人为本人的未开始，处理中的工单，排序由巡检时间由近及远
            //queryWrapper.between("status",PlanStatusEnum.NOT_STARTED.getCode(),PlanStatusEnum.STARTED.getCode()) ;
            queryWrapper.ne("status",PlanStatusEnum.OVER.getCode()) ;
            queryWrapper.orderByDesc("plan_start_time") ;
        }else{
            //关闭列表，经办人为本人的近7日完成的工单，排序由完成时间由近及远
            queryWrapper.eq("status",PlanStatusEnum.OVER.getCode()) ;
            Date sevenDate = LocalDateUtils.addDateDays(new Date(),-7) ;
            queryWrapper.ge("complate_time",sevenDate) ;
            queryWrapper.orderByDesc("complate_time") ;
        }

        IPage<UserInspectionPlanEntity> page = this.page(
                new Query<UserInspectionPlanEntity>().getPage(ObjectToMapUtils.setConditionMap(req)),
                queryWrapper
        );
        List<UserInspectionPlanRes> retList = new ArrayList<>() ;
        IPage<UserInspectionPlanRes> retPage = new Page<>(page.getCurrent(),page.getSize()) ;
        retPage.setPages(page.getPages()) ;
        retPage.setTotal(page.getTotal()) ;

        if (!CollectionUtils.isEmpty(page.getRecords())){
            //查询所有范围
            List<UserInspectionPlanScopeEntity> planScopeEntityList= userInspectionPlanScopeService.list() ;
            page.getRecords().forEach(e->{
                UserInspectionPlanRes res = new UserInspectionPlanRes() ;
                BeanUtils.copyProperties(e,res);
                //添加首次巡检时间
                res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
                //时间
                if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())){
                    res.setPlanTimeScope(LocalDateUtils.getWeekTimeStr(res.getPlanStartTime(),res.getPlanEndTime()));
                }else{
                    res.setPlanTimeScope(LocalDateUtils.getTimeStr(res.getPlanStartTime(),res.getPlanEndTime()));
                }
                res.setStatusDesc(PlanStatusEnum.getDesc(e.getStatus()));
                res.setResultDesc(PlanResultEnum.getDesc(e.getResult()));
                if (!CollectionUtils.isEmpty(planScopeEntityList)){
                    List<Long> scopeIdList = planScopeEntityList.stream().filter(p->p.getUserInspectionPlanId().equals(e.getId())).map(UserInspectionPlanScopeEntity::getScopeId).collect(Collectors.toList()) ;
                    res.setScopeList(scopeIdList);
                }
                retList.add(res) ;
            });
        }
        retPage.setRecords(retList) ;
        return new PageUtils(retPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitAndClose(AppUserInspectionSubmitAndCloseReq req,Long userId) {
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONORDER.getCode(),req.getId()) ;
        if (CollectionUtils.isEmpty(planAgentEntityList)){
            throw new RRException("巡检工单没有经办人") ;
        }

        Long count = planAgentEntityList.stream().filter(p->p.getAgentId().equals(userId)).count() ;
        if (count == 0){
            throw new RRException("当前登录人非经办人") ;
        }

        //1、验证记录存在
        UserInspectionPlanEntity planEntity = this.getById(req.getId()) ;
        if (planEntity == null || planEntity.getId() == null){
            throw new RRException("记录不存在") ;
        }
        //2、判断设备信息
        List<AppUserInspectionSubmitAndCloseReq.PlanResult> resultList = req.getPlanResultList() ;
        if (resultList == null || resultList.size()==0){
            throw new RRException("设备信息不能为空") ;
        }
        //3、判断设备结果,存在异常，订单异常
        AtomicReference<Boolean> isException = new AtomicReference<>(false);
        List<UserInspectionPlanScopeEntity> planScopeList = new ArrayList<>() ;
        List<UserInspectionPlanContentEntity> updateByIdList = new ArrayList<>() ;
        List<PicEntity> picEntityList = new ArrayList<>() ;
        resultList.forEach(e->{
            //更新检查结果
            //更新范围说明
            UserInspectionPlanScopeEntity planScopeEntity = userInspectionPlanScopeService.getById(e.getId()) ;
            if (planScopeEntity == null ||planScopeEntity.getId() == null){
                throw new RRException("范围参数错误"+e.getId()) ;
            }
            planScopeEntity.setExplain(e.getExplain());

            //上传图片
            List<String> picList = e.getPicList() ;
            if (!CollectionUtils.isEmpty(picList)){
                picList.forEach(p->{
                    PicEntity picEntity = new PicEntity() ;
                    picEntity.setPic(p);
                    picEntity.setType(BusiTypeEnum.INSPECTIONORDER.getCode());
                    picEntity.setBusiId(planScopeEntity.getId());
                    picEntityList.add(picEntity) ;
                });
            }

            List<AppUserInspectionSubmitAndCloseReq.PlanResult.Content> contentList = e.getContentList() ;
            if (CollectionUtils.isEmpty(contentList)){
                throw new RRException("巡检内容不能为空") ;
            }

            AtomicReference<Boolean> isTempException = new AtomicReference<>(false);
            contentList.forEach(pp->{
                if (pp.getResult()==1){
                    isException.set(true);
                    isTempException.set(true);
                }
                UserInspectionPlanContentEntity planContentEntity = userInspectionPlanContentService.getById(pp.getId()) ;
                planContentEntity.setResult(pp.getResult());
                updateByIdList.add(planContentEntity) ;
            });

            planScopeEntity.setResult(isTempException.get() ?PlanResultEnum.EXCEPTION.getCode():PlanResultEnum.NORMAL.getCode());
            planScopeList.add(planScopeEntity) ;
        });
        if (!CollectionUtils.isEmpty(picEntityList)) {
            picService.saveBatch(picEntityList);
        }
        if (!CollectionUtils.isEmpty(updateByIdList)) {
            userInspectionPlanContentService.updateBatchById(updateByIdList);
        }
        if (!CollectionUtils.isEmpty(planScopeList)) {
            userInspectionPlanScopeService.updateBatchById(planScopeList);
        }

        //4、更新记录
        planEntity.setResult(isException.get() ?PlanResultEnum.EXCEPTION.getCode():PlanResultEnum.NORMAL.getCode());
        planEntity.setStatus(PlanStatusEnum.OVER.getCode());
        planEntity.setComplateTime(new Date());
        planEntity.setUpdateBy(userId);
        planEntity.setUpdateTime(new Date());
        planEntity.setCheckType(1);
        updateById(planEntity) ;
    }

    @Override
    public void close(Long id, Long userId) {
        UserInspectionPlanEntity planEntity = getById(id) ;
        if (planEntity == null){
            throw new RRException("工单不存在") ;
        }
        //检查是否都有了结果，才能关闭
        QueryWrapper<UserInspectionPlanScopeEntity> planScopeEntityQueryWrapper = new QueryWrapper<>() ;
        planScopeEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanScopeEntity> planScopeEntityList = userInspectionPlanScopeService.list(planScopeEntityQueryWrapper) ;
        if (CollectionUtils.isEmpty(planScopeEntityList)){
            throw new RRException("没有巡检范围") ;
        }
        AtomicInteger result = new AtomicInteger(-1) ;
        planScopeEntityList.forEach(e->{
            if (e.getExecutorId() == null){
                throw new RRException("没有巡检完毕，关闭失败") ;
            }
            if (e.getResult()>result.get()){
                result.set(e.getResult());
            }
        });
        planEntity.setResult(result.get());
        planEntity.setStatus(PlanStatusEnum.OVER.getCode());
        planEntity.setComplateTime(new Date());
        planEntity.setUpdateTime(new Date());
        planEntity.setUpdateBy(userId);
        updateById(planEntity) ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitResult(AppUserInspectionSubmitResultReq req, Long userId) {
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONORDER.getCode(),req.getId()) ;
        if (CollectionUtils.isEmpty(planAgentEntityList)){
            throw new RRException("巡检工单没有经办人") ;
        }
        //1、验证记录存在
        UserInspectionPlanEntity planEntity = this.getById(req.getId()) ;
        if (planEntity == null || planEntity.getId() == null){
            throw new RRException("记录不存在") ;
        }
        Long count = planAgentEntityList.stream().filter(p->p.getAgentId().equals(userId)).count() ;
        if (count == 0){
            throw new RRException("当前登录人非经办人") ;
        }
        //2、判断设备信息
        AppUserInspectionSubmitResultReq.PlanResult result = req.getPlanResult() ;
        //3、判断设备结果,存在异常，订单异常
        //更新检查结果
        //更新范围说明
        UserInspectionPlanScopeEntity planScopeEntity = userInspectionPlanScopeService.getById(result.getId()) ;
        if (planScopeEntity == null ||planScopeEntity.getId() == null){
            throw new RRException("范围参数错误"+result.getId()) ;
        }

        //上传图片
        List<String> picList = result.getPicList() ;
        if (!CollectionUtils.isEmpty(picList)){
            List<PicEntity> picEntityList = new ArrayList<>() ;
            picList.forEach(p->{
                PicEntity picEntity = new PicEntity() ;
                picEntity.setPic(p);
                picEntity.setType(BusiTypeEnum.INSPECTIONORDER_SCOPE.getCode());
                picEntity.setBusiId(planScopeEntity.getId());
                picEntityList.add(picEntity) ;
            });
            picService.saveBatch(picEntityList) ;
        }

        List<AppUserInspectionSubmitResultReq.PlanResult.Content> contentList = result.getContentList() ;
        if (CollectionUtils.isEmpty(contentList)){
            throw new RRException("巡检内容不能为空") ;
        }
        List<UserInspectionPlanContentEntity> updateByIdList = new ArrayList<>() ;
        AtomicBoolean isException = new AtomicBoolean() ;
        contentList.forEach(pp->{
            if (pp.getResult()==1){
                isException.set(true);
            }
            UserInspectionPlanContentEntity planContentEntity = userInspectionPlanContentService.getById(pp.getId()) ;
            planContentEntity.setResult(pp.getResult());
            updateByIdList.add(planContentEntity) ;
        });
        userInspectionPlanContentService.updateBatchById(updateByIdList) ;

        planScopeEntity.setExplain(result.getExplain());
        planScopeEntity.setExecutorId(userId);
        if (isException.get()){
            planScopeEntity.setResult(PlanResultEnum.EXCEPTION.getCode());
        }else{
            planScopeEntity.setResult(PlanResultEnum.NORMAL.getCode());
        }
        userInspectionPlanScopeService.updateById(planScopeEntity) ;
    }

    @Override
    public InspectionOrderInfoByPlanIdRes queryByPlanId(Long id) {

        InspectionOrderInfoByPlanIdRes res = new InspectionOrderInfoByPlanIdRes() ;
        //根据计划获取当天的工单
        QueryWrapper<UserInspectionPlanEntity> planEntityQueryWrapper = new QueryWrapper<>() ;
        planEntityQueryWrapper.eq("plan_id",id) ;
        planEntityQueryWrapper.ne("status",PlanStatusEnum.OVER.getCode()) ;
        planEntityQueryWrapper.ge("create_time",LocalDateUtils.format(new Date(), DateUtils.DATE_PATTERN)) ;
        List<UserInspectionPlanEntity> planEntityList = list(planEntityQueryWrapper) ;

        if (CollectionUtils.isEmpty(planEntityList)){
            throw new RRException("没有巡检工单或已结束") ;
        }

        UserInspectionPlanEntity planEntity = planEntityList.get(0) ;

        if(planEntity==null||planEntity.getId()==null){
            throw new RRException("记录不存在") ;
        }
        BeanUtil.copyProperties(planEntity,res,true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        //查询经办人列表
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONORDER.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planAgentEntityList)){
            res.setAgentIdList(planAgentEntityList.stream().map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
        }
        //查询巡检范围
        QueryWrapper<UserInspectionPlanScopeEntity> scopeEntityQueryWrapper = new QueryWrapper<>() ;
        scopeEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanScopeEntity> scopeList = userInspectionPlanScopeService.list(scopeEntityQueryWrapper) ;
        if (!CollectionUtils.isEmpty(scopeList)){
            List<Long> scopeIdList = scopeList.stream().map(UserInspectionPlanScopeEntity::getScopeId).collect(Collectors.toList()) ;
            res.setScopeList(scopeIdList);
        }
        //提醒时间
        QueryWrapper<PlanRemindEntity> remindEntityQueryWrapper = new QueryWrapper<>() ;
        remindEntityQueryWrapper.eq("plan_id",planEntity.getPlanId()) ;
        List<PlanRemindEntity> remindList = remindService.list(remindEntityQueryWrapper) ;
        res.setRemindList(remindList.stream().map(PlanRemindEntity::getLeadTime).collect(Collectors.toList()));
        //巡检内容
        QueryWrapper<UserInspectionPlanContentEntity> contentEntityQueryWrapper = new QueryWrapper<>() ;
        contentEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanContentEntity> contentPlanList = userInspectionPlanContentService.list(contentEntityQueryWrapper) ;
        List<String> contentList = new ArrayList<>() ;
        contentPlanList.forEach(e->{
            if (!contentList.contains(e.getContent())){
                contentList.add(e.getContent()) ;
            }
        });
        res.setContentList(contentList);
        //巡检内容,选件图片是巡检范围的图片
        List<PicEntity> picEntityList = picService.listByType(BusiTypeEnum.INSPECTIONORDER.getCode()) ;
        List<InspectionOrderInfoByPlanIdRes.PlanResult> planResultList = new ArrayList<>() ;

        scopeList.forEach(e->{

            InspectionOrderInfoByPlanIdRes.PlanResult result = new InspectionOrderInfoByPlanIdRes.PlanResult() ;
            BeanUtil.copyProperties(e,result,true,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            result.setPicList(picEntityList.stream().filter(p->p.getBusiId().equals(e.getId())).map(PicEntity::getPic).collect(Collectors.toList()));

            List<InspectionOrderInfoByPlanIdRes.PlanResult.Content> resultContent = new ArrayList<>() ;
            contentPlanList.stream().filter(p->p.getUserInspectionPlanScopeId().equals(e.getId())).forEach(pp->{
                InspectionOrderInfoByPlanIdRes.PlanResult.Content content = new InspectionOrderInfoByPlanIdRes.PlanResult.Content() ;
                BeanUtil.copyProperties(pp,content,true,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                resultContent.add(content) ;
            });

            result.setContentList(resultContent);
            planResultList.add(result) ;
        });

        res.setPlanResultList(planResultList);
        res.setStatusDesc(PlanStatusEnum.getDesc(res.getStatus()));
        res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
        //时间
        if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())||FrequencyEnum.WORKING.getCode().equals(res.getFrequency())) {
            res.setPlanTimeScope(LocalDateUtils.getWeekTimeStr(res.getPlanStartTime(), res.getPlanEndTime()));
        }else{
            res.setPlanTimeScope(LocalDateUtils.getTimeStr(res.getPlanStartTime(),res.getPlanEndTime()));
        }
        return res ;
    }

    @Override
    public UserInspectionPlanInfoForPlatRes queryPlatInfoById(Long id) {
        UserInspectionPlanInfoForPlatRes res = new UserInspectionPlanInfoForPlatRes() ;
        UserInspectionPlanEntity planEntity= getById(id) ;
        if(planEntity==null||planEntity.getId()==null){
            throw new RRException("记录不存在") ;
        }
        BeanUtil.copyProperties(planEntity,res,true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        //查询经办人列表
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONORDER.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planAgentEntityList)){
            res.setAgentIdList(planAgentEntityList.stream().map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
        }
        //查询巡检范围
        QueryWrapper<UserInspectionPlanScopeEntity> scopeEntityQueryWrapper = new QueryWrapper<>() ;
        scopeEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanScopeEntity> scopeList = userInspectionPlanScopeService.list(scopeEntityQueryWrapper) ;
        if (!CollectionUtils.isEmpty(scopeList)){
            List<Long> scopeIdList = scopeList.stream().map(UserInspectionPlanScopeEntity::getScopeId).collect(Collectors.toList()) ;
            res.setScopeList(scopeIdList);
        }
        //提醒时间
        QueryWrapper<PlanRemindEntity> remindEntityQueryWrapper = new QueryWrapper<>() ;
        remindEntityQueryWrapper.eq("plan_id",planEntity.getPlanId()) ;
        List<PlanRemindEntity> remindList = remindService.list(remindEntityQueryWrapper) ;
        res.setRemindList(remindList.stream().map(PlanRemindEntity::getLeadTime).collect(Collectors.toList()));
        //巡检内容
        QueryWrapper<UserInspectionPlanContentEntity> contentEntityQueryWrapper = new QueryWrapper<>() ;
        contentEntityQueryWrapper.eq("user_inspection_plan_id",id) ;
        List<UserInspectionPlanContentEntity> contentPlanList = userInspectionPlanContentService.list(contentEntityQueryWrapper) ;
        List<String> contentList = new ArrayList<>() ;
        contentPlanList.forEach(e->{
            if (!contentList.contains(e.getContent())){
                contentList.add(e.getContent()) ;
            }
        });
        res.setContentList(contentList);
        //巡检内容,选件图片是巡检范围的图片
        List<PicEntity> picEntityList = picService.listByType(BusiTypeEnum.INSPECTIONORDER_SCOPE.getCode()) ;
        List<UserInspectionPlanInfoForPlatRes.PlanResult> planResultList = new ArrayList<>() ;

        Set<Long> executorIdSet = new HashSet<>() ;
        scopeList.forEach(e->{
            if (e.getExecutorId()!=null) {
                executorIdSet.add(e.getExecutorId());
            }
            UserInspectionPlanInfoForPlatRes.PlanResult result = new UserInspectionPlanInfoForPlatRes.PlanResult() ;
            BeanUtil.copyProperties(e,result,true,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            result.setPicList(picEntityList.stream().filter(p->p.getBusiId().equals(e.getId())).map(PicEntity::getPic).collect(Collectors.toList()));

            List<UserInspectionPlanInfoForPlatRes.PlanResult.Content> resultContent = new ArrayList<>() ;
            contentPlanList.stream().filter(p->p.getUserInspectionPlanScopeId().equals(e.getId())).forEach(pp->{
                UserInspectionPlanInfoForPlatRes.PlanResult.Content content = new UserInspectionPlanInfoForPlatRes.PlanResult.Content() ;
                BeanUtil.copyProperties(pp,content,true,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                resultContent.add(content) ;
            });

            result.setContentList(resultContent);
            planResultList.add(result) ;
        });

        if (executorIdSet.size()>0) {
            res.setExecutorIdList(executorIdSet.stream().distinct().collect(Collectors.toList()));
        }
        
        res.setPlanResultList(planResultList);
        res.setStatusDesc(PlanStatusEnum.getDesc(res.getStatus()));
        res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
        //时间
        if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())||FrequencyEnum.WORKING.getCode().equals(res.getFrequency())) {
            res.setPlanTimeScope(LocalDateUtils.getWeekTimeStr(res.getPlanStartTime(), res.getPlanEndTime()));
        }else{
            res.setPlanTimeScope(LocalDateUtils.getTimeStr(res.getPlanStartTime(),res.getPlanEndTime()));
        }
        return res ;
    }

    @Override
    public List<EquipmentStatusRes> getEquipmentStatusList() {
        QueryWrapper<UserInspectionPlanScopeEntity> wrapper   = new QueryWrapper<>() ;
        wrapper.in("result",1, 2) ;
        wrapper.orderByDesc("id") ;
        List<UserInspectionPlanScopeEntity> list = userInspectionPlanScopeService.list(wrapper) ;
        if (!CollectionUtils.isEmpty(list)){
            List<EquipmentStatusRes> retList = new ArrayList<>() ;
            Map<Long, List<UserInspectionPlanScopeEntity>> map = list.stream().collect(Collectors.groupingBy(UserInspectionPlanScopeEntity::getScopeId));
            map.keySet().stream().forEach(e->{
                List<UserInspectionPlanScopeEntity> subList = map.get(e) ;
                if (!CollectionUtils.isEmpty(subList)) {
                    EquipmentStatusRes res = new EquipmentStatusRes() ;
                    UserInspectionPlanScopeEntity planScopeEntity = subList.get(0) ;
                    res.setEquipmentId(planScopeEntity.getScopeId());
                    res.setResult(planScopeEntity.getResult());
                    res.setResultDesc(PlanResultEnum.getDesc(planScopeEntity.getResult()));
                    retList.add(res);
                }
            });
            return retList ;
        }
        return null;
    }

    public void createUserPlan(InspectionPlanRes e){
        UserInspectionPlanEntity userInspectionPlanEntity = new UserInspectionPlanEntity() ;
        FrequencyEnum frequencyEnum = FrequencyEnum.valueOf(e.getFrequency()) ;
        if (frequencyEnum == null){
            throw new RRException("频率错误") ;
        }
        switch (frequencyEnum){
            case NO_REPEAT:
                //不重复，只执行一次，到期时间就执行
                try {
                    Integer dayCount = LocalDateUtils.getDayCount(new Date(),e.getFirstStartTime()) ;
                    if (dayCount==0){
                        //判断开始状态，默认没开始
                        userInspectionPlanEntity.setPlanStartTime(e.getFirstStartTime());
                        userInspectionPlanEntity.setPlanEndTime(e.getFirstEndTime());
                        userInspectionPlanEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
                        createUserPlan(e,userInspectionPlanEntity) ;
                    }
                } catch (ParseException parseException) {
                    parseException.printStackTrace();
                }
                break;
            case DAY:
                //当天时间同首次计划时间比较天数
                try {
                    Integer dayCount = LocalDateUtils.getDayCount(new Date(),e.getFirstStartTime()) ;
                    userInspectionPlanEntity.setPlanStartTime(LocalDateUtils.addDateDays(e.getFirstStartTime(),dayCount));
                    userInspectionPlanEntity.setPlanEndTime(LocalDateUtils.addDateDays(e.getFirstEndTime(),dayCount));
                    //判断开始状态，默认没开始
                    userInspectionPlanEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
                    createUserPlan(e,userInspectionPlanEntity) ;
                } catch (ParseException parseException) {
                    parseException.printStackTrace();
                }
                break;
            case WEEK:
                //判断首次开始的星期，判断当前星期
                if (LocalDateUtils.compareWeek(new Date(),e.getFirstStartTime())==0){
                    try {
                        Integer dayCount = LocalDateUtils.getDayCount(new Date(),e.getFirstStartTime()) ;
                        userInspectionPlanEntity.setPlanStartTime(LocalDateUtils.addDateDays(e.getFirstStartTime(),dayCount));
                        userInspectionPlanEntity.setPlanEndTime(LocalDateUtils.addDateDays(e.getFirstEndTime(),dayCount));
                        //判断开始状态
                        userInspectionPlanEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
                        createUserPlan(e,userInspectionPlanEntity) ;
                    } catch (ParseException parseException) {
                        parseException.printStackTrace();
                    }
                }
                break ;
            case MONTH:
                //判断首次开始的星期，判断当前星期
                if (LocalDateUtils.compareMonthDay(new Date(),e.getFirstStartTime())==0){
                    try {
                        Integer dayCount = LocalDateUtils.getDayCount(new Date(),e.getFirstStartTime()) ;
                        userInspectionPlanEntity.setPlanStartTime(LocalDateUtils.addDateDays(e.getFirstStartTime(),dayCount));
                        userInspectionPlanEntity.setPlanEndTime(LocalDateUtils.addDateDays(e.getFirstEndTime(),dayCount));
                        //判断开始状态
                        userInspectionPlanEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
                        createUserPlan(e,userInspectionPlanEntity) ;
                    } catch (ParseException parseException) {
                        parseException.printStackTrace();
                    }
                }
                break ;
            case YEAR:
                //判断首次开始的星期，判断当前星期
                if (LocalDateUtils.compareYearDay(new Date(),e.getFirstStartTime())==0){
                    try {
                        Integer dayCount = LocalDateUtils.getDayCount(new Date(),e.getFirstStartTime()) ;
                        userInspectionPlanEntity.setPlanStartTime(LocalDateUtils.addDateDays(e.getFirstStartTime(),dayCount));
                        userInspectionPlanEntity.setPlanEndTime(LocalDateUtils.addDateDays(e.getFirstEndTime(),dayCount));
                        //判断开始状态
                        userInspectionPlanEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
                        createUserPlan(e,userInspectionPlanEntity) ;
                    } catch (ParseException parseException) {
                        parseException.printStackTrace();
                    }
                }
                break ;
            case WORKING:
                //判断工作日生成工单
                if (LocalDateUtils.checkSameDayAndWeekdays(new Date(),e.getFirstEndTime())){
                    try {
                        Integer dayCount = LocalDateUtils.getDayCount(new Date(),e.getFirstStartTime()) ;
                        userInspectionPlanEntity.setPlanStartTime(LocalDateUtils.addDateDays(e.getFirstStartTime(),dayCount));
                        userInspectionPlanEntity.setPlanEndTime(LocalDateUtils.addDateDays(e.getFirstEndTime(),dayCount));
                        //判断开始状态
                        userInspectionPlanEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
                        createUserPlan(e,userInspectionPlanEntity) ;
                    } catch (ParseException parseException) {
                        parseException.printStackTrace();
                    }
                }
                break;
            default:break;
        }
    }

    private void createUserPlan(InspectionPlanRes e,UserInspectionPlanEntity userInspectionPlanEntity){

        //1、添加用户记录
        userInspectionPlanEntity.setPlanId(e.getId());
        userInspectionPlanEntity.setName(e.getName()+"-"+(e.getNum()+1));
        userInspectionPlanEntity.setCode(CodeUtils.getCode(Constants.INSPECITION_CODE_BEGIN_WITH,Constants.CODE_LEN));
        userInspectionPlanEntity.setIsDel(0);
        userInspectionPlanEntity.setCreateTime(new Date());
        userInspectionPlanEntity.setCreateBy(e.getCreateBy());
        userInspectionPlanEntity.setUpdateBy(e.getCreateBy());
        userInspectionPlanEntity.setUpdateTime(new Date());
        //添加频率
        userInspectionPlanEntity.setFrequency(e.getFrequency());
        //结束时间+计划结束的时分
        //添加记录
        this.save(userInspectionPlanEntity) ;


        //修改计划次数
        InspectionPlanEntity inspectionPlanEntity = new InspectionPlanEntity() ;
        inspectionPlanEntity.setId(e.getId());
        inspectionPlanEntity.setNum(e.getNum()+1);
        inspectionPlanService.updateById(inspectionPlanEntity) ;

        //用户订单id
        Long userInspectionPlanId = userInspectionPlanEntity.getId() ;
        //添加经办人
        if (!CollectionUtils.isEmpty(e.getAgentIdList())){
            List<PlanAgentEntity> planAgentEntityList = new ArrayList<>() ;
            e.getAgentIdList().forEach(pa->{
                PlanAgentEntity planAgentEntity = new PlanAgentEntity() ;
                planAgentEntity.setType(BusiTypeEnum.INSPECTIONORDER.getCode());
                planAgentEntity.setPlanId(userInspectionPlanId);
                planAgentEntity.setAgentId(pa);
                planAgentEntityList.add(planAgentEntity) ;
            });
            planAgentService.saveBatch(planAgentEntityList) ;
        }
        //2、添加范围
        List<UserInspectionPlanScopeEntity> userInspectionPlanScopeEntityList =  new ArrayList<>() ;
        e.getScopeIdList().forEach(p->{
            UserInspectionPlanScopeEntity userInspectionPlanScopeEntity = new UserInspectionPlanScopeEntity() ;
            userInspectionPlanScopeEntity.setUserInspectionPlanId(userInspectionPlanId);
            userInspectionPlanScopeEntity.setScopeId(p);
            userInspectionPlanScopeEntity.setResult(-1);
            userInspectionPlanScopeEntityList.add(userInspectionPlanScopeEntity) ;
        });
        userInspectionPlanScopeService.saveBatch(userInspectionPlanScopeEntityList) ;
        //3、添加内容
        List<UserInspectionPlanContentEntity> userInspectionPlanContentEntityList = new ArrayList<>() ;
        userInspectionPlanScopeEntityList.stream().forEach(pp->{
            e.getContentList().forEach(c->{
                UserInspectionPlanContentEntity userInspectionPlanContentEntity = new UserInspectionPlanContentEntity() ;
                userInspectionPlanContentEntity.setUserInspectionPlanId(userInspectionPlanId);
                userInspectionPlanContentEntity.setUserInspectionPlanScopeId(pp.getId());
                userInspectionPlanContentEntity.setContent(c);
                userInspectionPlanContentEntity.setResult(-1);
                userInspectionPlanContentEntityList.add(userInspectionPlanContentEntity) ;
            });
        });
        userInspectionPlanContentService.saveBatch(userInspectionPlanContentEntityList) ;
    }
}